using System.Collections.Generic;
using System.IO;
using System.Text;
using Sirenix.OdinInspector;
using UnityEditor;
using UnityEngine;

namespace BearUtil
{
    public class CreateNodeBasic<T> : BearScriptableObject<T> where T : BearScriptableObject<T> 
    {
        [ReadOnly, LabelText("文件生成路径"), ShowInInspector]
        public virtual string GeneratePath { get; }

        [ReadOnly, LabelText("格式生成路径"), ShowInInspector]
        public virtual string FormatPath { get; }

        [ReadOnly, LabelText("格式文件名称"), ShowInInspector]
        public virtual string FileName { get; }

        /// <summary>
        /// 管理动态节点
        /// </summary>
        [ShowInInspector, LabelText("动态节点集"), TabGroup("查看")]
        protected List<DynamicProp> _nodes;

        [LabelText("固定属性"), InfoBox("不要随便删除，固定属性", InfoMessageType.Warning), TabGroup("静态属性")]
        public List<NodeProperty> StaticProperty;

        [SerializeField, TabGroup("使用")] protected DynamicProp node;

        /// <summary>
        /// 返回节点
        /// </summary>
        /// <returns></returns>
        public List<DynamicProp> GetNodes()
        {
            return _nodes;
        }

        // 是否存在节点
        private bool hasNode
        {
            get { return node != null; }
        }

        [LabelText("节点名称"), HideIf("hasNode"), TabGroup("使用"), OnValueChanged("StringCheck")]
        public string NodeName;

        private void StringCheck(string value)
        {
            NodeName = NodeMethodUtil.ClassNameOnly(value);
        }

        public virtual void NewNode()
        {
           
        }

        [Button("刷新节点", ButtonSizes.Large), TabGroup("使用")]
        public virtual void UpdateNodes()
        {
            if (node != null)
                node = null;

            CtrlAllDynamicNode();
        }

        [Button("删除节点", ButtonSizes.Large), TabGroup("使用")]
        public void ClearNode()
        {
            if (node == null)
                return;

            if (EditorUtility.DisplayDialog("提醒", "清理当前节点？", "ok", "no"))
            {
                NodeMethodUtil.Delete(GeneratePath, node.Name + ".cs");

                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(node));
                AssetDatabase.Refresh();
            }
        }

        // dynamic node 收集管理
        public void CtrlAllDynamicNode()
        {
            if (_nodes == null)
                _nodes = new List<DynamicProp>();

            _nodes.Clear();
            // 检索 default 路径，管理 dynamic nodes
            string folderPath = Application.dataPath.Replace("Assets", GeneratePath);

            if (!Directory.Exists(folderPath))
            {
                Debug.LogError("[CreateNewNode]指向路径丢失，请创建指定路径");
                return;
            }

            var files = Directory.GetFiles(folderPath, "**.asset", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                var file = files[i];
                var path = file.Replace(Application.dataPath, "Assets");

                var node = AssetDatabase.LoadAssetAtPath<DynamicProp>(path);
                if (node == null)
                    continue;

                _nodes.Add(node);
            }
        }

        protected string GetPropLine(NodeProperty p)
        {
            StringBuilder scriptTxt = new StringBuilder();
            switch (p.Type)
            {
                case NodePropertyType.Vector2:
                    scriptTxt.Append($"\t[Description(\"{p.Desc}_x\")] ");
                    scriptTxt.Append($"public float {p.PropName}_x;\n");
                    scriptTxt.Append($"\t[Description(\"{p.Desc}_y\")] ");
                    scriptTxt.Append($"public float {p.PropName}_y;\n");
                    break;
                default:
                    scriptTxt.Append($"\t[Description(\"{p.Desc}\")] ");
                    scriptTxt.Append($"public {GetType(p.Type)} {p.PropName};\n");
                    break;
            }

            return scriptTxt.ToString();
        }

        protected string GetType(NodePropertyType type)
        {
            switch (type)
            {
                case NodePropertyType.Boolean:
                    return "bool";
                case NodePropertyType.Float:
                    return "float";
                case NodePropertyType.Node:
                case NodePropertyType.ArrayInt:
                    return "int[]";
                case NodePropertyType.AudioPlayData:
                case NodePropertyType.String:
                    return "string";
                case NodePropertyType.ArrayString:
                    return "string[]";
                case NodePropertyType.ActorID:
                case NodePropertyType.Int:
                case NodePropertyType.Direction:
                    return "int";
                case NodePropertyType.Line:
                    break;
                default:
                    var dp = CreateNewProperty.Instance.GetProperty(type.ToString());
                    if (dp == null)
                    {
                        Debug.LogError("[CreateNewNode]Type lost: " + type.ToString());
                        return "";
                    }
                    else
                        return dp.PType.ToString().ToLower();
            }

            return "";
        }

        public virtual void UpdateFormat()
        {
        }
    }
}